/*
 ------------------------------------------------------------------------------
 Copyright (C) 2013 Eternal Games.

 This file is part of the GLQuake source code.

 The GLQuake source code is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or (at your
 option) any later version.

 The GLQuake source code is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 more details.

 You should have received a copy of the GNU General Public License along with
 the GLQuake source code; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 ------------------------------------------------------------------------------
*/


//
// infoString.cpp - ...
//


#include "shared.h"


/*
 ==================
 Info_SetValueForKey
 ==================
*/
bool Info_SetValueForKey (char *infoString, const char *key, const char *value){

	char	check[MAX_STRING_LENGTH];
	char	pair[MAX_STRING_LENGTH];
	char	*start;
	char	*in;
	char	*out;
	int		len;

	if (!infoString)
		return false;

	// Remove the key/value pair if available
	in = infoString;

	while (*in){
		start = in;

		if (*in == '\\')
			in++;

		// Get the key
		out = check;

		while (*in != '\\'){
			if (!*in)
				break;

			*out++ = *in++;
		}

		if (!*in)
			break;

		*out = 0;
		in++;

		// Skip the value
		while (*in != '\\'){
			if (!*in)
				break;

			in++;
		}

		// Check if this is the desired key
		if (!Str_ICompare(check, key)){
			// Remove this key/value pair
			while (*in)
				*start++ = *in++;

			*start = 0;

			break;
		}
	}


	// Add a new key/value pair
	len = Str_SPrintf(pair, sizeof(pair), "\\%s\\%s", key, value);

	if (len < 0 || Str_Length(infoString) + len >= MAX_STRING_LENGTH)
		return false;

	Str_Append(infoString, pair, MAX_STRING_LENGTH);

	return true;
}

/*
 ==================
 Info_GetValueForKey
 ==================
*/
bool Info_GetValueForKey (const char *infoString, const char *key, char *value){

	char		check[MAX_STRING_LENGTH];
	const char	*in;
	char		*out;

	if (!infoString)
		return false;

	in = infoString;

	while (*in){
		if (*in == '\\')
			in++;

		// Get the key
		out = check;

		while (*in != '\\'){
			if (!*in)
				break;

			*out++ = *in++;
		}

		if (!*in)
			break;

		*out = 0;
		in++;

		// Get the value
		out = value;

		while (*in != '\\'){
			if (!*in)
				break;

			*out++ = *in++;
		}

		*out = 0;

		// Check if this is the desired key
		if (!Str_ICompare(check, key))
			return true;
	}

	// Key not found
	*value = 0;

	return false;
}

/*
 ==================
 Info_RemoveKey
 ==================
*/
void Info_RemoveKey (char *infoString, const char *key){

	char	check[MAX_STRING_LENGTH];
	char	*start;
	char	*in;
	char	*out;

	if (!infoString)
		return;

	in = infoString;

	while (*in){
		start = in;

		if (*in == '\\')
			in++;

		// Get the key
		out = check;

		while (*in != '\\'){
			if (!*in)
				break;

			*out++ = *in++;
		}

		if (!*in)
			break;

		*out = 0;
		in++;

		// Skip the value
		while (*in != '\\'){
			if (!*in)
				break;

			in++;
		}

		// Check if this is the desired key
		if (!Str_ICompare(check, key)){
			// Remove this key/value pair
			while (*in)
				*start++ = *in++;

			*start = 0;

			return;
		}
	}
}

/*
 ==================
 Info_NextPair
 ==================
*/
const char *Info_NextPair (const char *infoString, char *key, char *value){

	const char	*in;
	char		*out;

	*key = 0;
	*value = 0;

	if (!infoString || !*infoString)
		return NULL;

	in = infoString;

	if (*in == '\\')
		in++;

	// Get the key
	out = key;

	while (*in != '\\'){
		if (!*in){
			*out = 0;

			return in;
		}

		*out++ = *in++;
	}

	*out = 0;
	in++;

	// Get the value
	out = value;

	while (*in != '\\'){
		if (!*in){
			*out = 0;

			return in;
		}

		*out++ = *in++;
	}

	*out = 0;

	return in;
}

/*
 ==================
 Info_Clear
 ==================
*/
void Info_Clear (char *infoString){

	if (!infoString)
		return;

	*infoString = 0;
}

/*
 ==================
 Info_Print
 ==================
*/
void Info_Print (const char *infoString, void (*printf)(const char *fmt, ...)){

	char		key[MAX_STRING_LENGTH];
	char		value[MAX_STRING_LENGTH];
	const char	*in;
	char		*out;

	if (!infoString)
		return;

	in = infoString;

	while (*in){
		if (*in == '\\')
			in++;

		// Get the key
		out = key;

		while (*in != '\\'){
			if (!*in)
				break;

			*out++ = *in++;
		}

		if (!*in)
			break;

		*out = 0;
		in++;

		// Get the value
		out = value;

		while (*in!= '\\'){
			if (!*in)
				break;

			*out++ = *in++;
		}

		*out = 0;

		// Print the key/value pair
		printf("%-32s \"%s" S_COLOR_DEFAULT "\"\n", key, value);
	}
}